Index Concurrency

Latch Modes

Read Mode

Write Mode

Latch Implementations

Test-and-Set Spin Latch (TAS)

使用一个 atomic 的值表示锁,在请求锁时尝试更改该值,若以被锁上则循环等待直到其它线程解锁。

std::atomic<bool> latch;
// ...
while (latch.test_and_set(…)) {
 // Retry? Yield? Abort?
}

Blocking OS Mutex

会 fallback 到内核中的 mutex,较慢

std::mutex m;
// ...
m.lock();
// Do something special...
m.unlock();

Reader-Writer Latches


Hash Table Latching

Page Latches

Slot Latches


B+ Tree Concurrency Control

Two types of problems:

Latch Crabbing / Coupling

定义“安全”的节点:更新时不进行分裂和合并的节点

为了让 B+ 树能被多个线程同时进行访问和修改,在访问节点时,在访问过程中将根节点到目标节点上所有节点进行上锁,只有当遍历到“安全”的节点时,才能释放其祖先节点的锁。

Find: Start at root and traverse down the tree:

Insert / Delete: Start at root and go down, obtaining W latches as needed. Once child is latched, check if it is safe:

Better Latching Algorithm

由于上面的方法在对 B+ 树进行修改操作时必须对根节点以及部分内部节点上锁,在性能上有所不足。

多数对 B+ 树的修改都不会造成分裂或合并,可以先假设修改操作不会造成分裂或合并,在遍历树时使用读锁。如果遍历发现这次修改操作确实需要进行分裂或合并,再使用上面的方法(即使用写锁)重新遍历并更新。

This approach optimistically assumes that only leaf node will be modified; if not, R latches set on the first pass to leaf are wasteful.

叶子节点间的并发

在只进行读操作时,无需特殊操作。

当一个线程要读取兄弟节点,而另一个线程正在写入该兄弟节点时,可以选择在经过几次获取锁的尝试后 kill 读取线程。

点此查看原文